package cn.ilikes.tools.untils;

import java.lang.reflect.Field;
import java.math.BigDecimal;

import org.apache.hadoop.hbase.util.Bytes;
import org.slf4j.Logger;

import cn.ilikes.tools.hbase.jpa.JPAHBaseRuntimeException;
import cn.ilikes.tools.logs.Loggerfactory;

public final class HBaseUtils {
	/** the log used by this class. */
	private static Logger logger = Loggerfactory.instance(HBaseUtils.class);

	/**
	 * 
	 * @param columnName
	 * @param index
	 *                  " jap @column Name = "family@qualifier"  or "
	 *                  family"   ;  index '@'  "
	 * @return
	 */
	public static String getfamily(String columnName, int index) {
		//		int index =columnName.indexOf(SysConfigs.hbase_column_family_qualifier) ;
		if (index != -1)
			return columnName.substring(0, index);
		return columnName;
	}

	public static String getQualifier(String columnName, int index) {
		//		int index =columnName.indexOf(SysConfigs.hbase_column_family_qualifier) ;
		if (index != -1)
			return columnName.substring(index + 1);
		return columnName;
	}
	
	public static Object getByteTosObject(byte[] value, Class  clazz) {
		if (/* isId || */clazz.isAssignableFrom(String.class)) {
			return Bytes.toString(value);
		} else if (clazz.equals(int.class) || clazz.isAssignableFrom(Integer.class)) {
			return Bytes.toInt(value);
		} else if (clazz.equals(long.class) || clazz.isAssignableFrom(Long.class)) {
			return Bytes.toLong(value);
		} else if (clazz.equals(boolean.class) || clazz.isAssignableFrom(Boolean.class)) {
			return Bytes.toBoolean(value);
		} else if (clazz.equals(double.class) || clazz.isAssignableFrom(Double.class)) {
			return Bytes.toDouble(value);
		}
		// else if (clazz.isAssignableFrom(java.util.UUID.class))
		// {
		// return Bytes.toBytes(value.toString());
		// }
		else if (clazz.equals(float.class) || clazz.isAssignableFrom(Float.class)) {
			return Bytes.toFloat(value);
		} else if (clazz.equals(short.class) || clazz.isAssignableFrom(Short.class)) {
			return Bytes.toShort(value);
		} else if (clazz.equals(BigDecimal.class)) {
			return Bytes.toBigDecimal(value);
		} else {
			throw new JPAHBaseRuntimeException(" clazz  " + clazz + " to byte[]  is error ! ");
		}
	}
	

	public static Object getByteTosObject(byte[] value, Field field) {
		Class<?> clazz = field.getType();
		return getByteTosObject(value,clazz);
//		Class<?> clazz = field.getType();
//		if (/* isId || */clazz.isAssignableFrom(String.class)) {
//			return Bytes.toString(value);
//		} else if (clazz.equals(int.class) || clazz.isAssignableFrom(Integer.class)) {
//			return Bytes.toInt(value);
//		} else if (clazz.equals(long.class) || clazz.isAssignableFrom(Long.class)) {
//			return Bytes.toLong(value);
//		} else if (clazz.equals(boolean.class) || clazz.isAssignableFrom(Boolean.class)) {
//			return Bytes.toBoolean(value);
//		} else if (clazz.equals(double.class) || clazz.isAssignableFrom(Double.class)) {
//			return Bytes.toDouble(value);
//		}
//		// else if (clazz.isAssignableFrom(java.util.UUID.class))
//		// {
//		// return Bytes.toBytes(value.toString());
//		// }
//		else if (clazz.equals(float.class) || clazz.isAssignableFrom(Float.class)) {
//			return Bytes.toFloat(value);
//		} else if (clazz.equals(short.class) || clazz.isAssignableFrom(Short.class)) {
//			return Bytes.toShort(value);
//		} else if (clazz.equals(BigDecimal.class)) {
//			return Bytes.toBigDecimal(value);
//		} else {
//			throw new JPAHBaseRuntimeException(" clazz  " + clazz + " to byte[]  is error ! ");
//		}
	}

	/**
	 * @param value
	 * @param clazz
	 * @return
	 */
	private static byte[] getBytes(Object value, Class<?> clazz) {
		if (/* isId || */clazz.isAssignableFrom(String.class)) {
			return Bytes.toBytes(value.toString());
		} else if (clazz.equals(int.class) || clazz.isAssignableFrom(Integer.class)) {
			return Bytes.toBytes(Integer.parseInt(value.toString()));
		} else if (clazz.equals(long.class) || clazz.isAssignableFrom(Long.class)) {
			return Bytes.toBytes(Long.parseLong(value.toString()));
		} else if (clazz.equals(boolean.class) || clazz.isAssignableFrom(Boolean.class)) {
			return Bytes.toBytes(Boolean.valueOf(value.toString()));
		} else if (clazz.equals(double.class) || clazz.isAssignableFrom(Double.class)) {
			return Bytes.toBytes(Double.valueOf(value.toString()));
		}
		// else if (clazz.isAssignableFrom(java.util.UUID.class))
		// {
		// return Bytes.toBytes(value.toString());
		// }
		else if (clazz.equals(float.class) || clazz.isAssignableFrom(Float.class)) {
			return Bytes.toBytes(Float.valueOf(value.toString()));
		} else if (clazz.equals(short.class) || clazz.isAssignableFrom(Short.class)) {
			return Bytes.toBytes(Short.valueOf(value.toString()));
		} else if (clazz.equals(BigDecimal.class)) {
			return Bytes.toBytes(BigDecimal.valueOf(new Long(value.toString())));
		} else {
			throw new JPAHBaseRuntimeException(" clazz  " + clazz + " to byte[]  is error ! ");
			//			if (value.getClass().isAssignableFrom(String.class)) {
			//				value = PropertyAccessorFactory.getPropertyAccessor(clazz).fromString(clazz, value.toString());
			//			}
			//			return PropertyAccessorFactory.getPropertyAccessor(clazz).toBytes(value);
		}
	}

	/**
	 * Returns bytes value for given value.
	 * 
	 * @param fieldName
	 *                  field name.
	 * @param m
	 *                  entity metadata
	 * @param value
	 *                  value.
	 * @return bytes value.
	 */
	public static byte[] getBytes(Object o) {
		if (o != null) {
			return getBytes(o, o.getClass());
		}

		return null;
	}

	//	public static Object fromBytes(EntityMetadata m, byte[] b) {
	//		Class idFieldClass = m.getIdAttribute().getJavaType();
	//		return fromBytes(b, idFieldClass);
	//	}

	//	public static Object fromBytes(byte[] b, Class<?> clazz) {
	//
	//		if (clazz.isAssignableFrom(String.class)) {
	//			return Bytes.toString(b);
	//		} else if (clazz.equals(int.class) || clazz.isAssignableFrom(Integer.class)) {
	//			return Bytes.toInt(b);
	//		} else if (clazz.equals(long.class) || clazz.isAssignableFrom(Long.class)) {
	//			return Bytes.toLong(b);
	//		} else if (clazz.equals(boolean.class) || clazz.isAssignableFrom(Boolean.class)) {
	//			return Bytes.toBoolean(b);
	//		} else if (clazz.equals(double.class) || clazz.isAssignableFrom(Double.class)) {
	//			return Bytes.toDouble(b);
	//		}
	//		// else if (clazz.isAssignableFrom(java.util.UUID.class))
	//		// {
	//		// return Bytes.toBytes(b.toString());
	//		// }
	//		else if (clazz.equals(float.class) || clazz.isAssignableFrom(Float.class)) {
	//			return Bytes.toFloat(b);
	//		} else if (clazz.equals(short.class) || clazz.isAssignableFrom(Short.class)) {
	//			return Bytes.toShort(b);
	//		} else if (clazz.equals(BigDecimal.class)) {
	//			return Bytes.toBigDecimal(b);
	//		} else {
	//			return PropertyAccessorFactory.getPropertyAccessor(clazz).fromBytes(clazz, b);
	//		}
	//	}

	/**
	 * Gets the operator.
	 * 
	 * @param condition
	 *                  the condition
	 * @param idPresent
	 *                  the id present
	 * @return the operator
	 */
	//	public static CompareOp getOperator(String condition, boolean idPresent) {
	//		if (/* !idPresent && */condition.equals("=")) {
	//			return CompareOp.EQUAL;
	//		} else if (/* !idPresent && */condition.equals(">")) {
	//			return CompareOp.GREATER;
	//		} else if (/* !idPresent && */condition.equals("<")) {
	//			return CompareOp.LESS;
	//		} else if (condition.equals(">=")) {
	//			return CompareOp.GREATER_OR_EQUAL;
	//		} else if (condition.equals("<=")) {
	//			return CompareOp.LESS_OR_EQUAL;
	//		} else {
	//			if (!idPresent) {
	//				throw new UnsupportedOperationException(" Condition " + condition + " is not suported in  hbase!");
	//			} else {
	//				throw new UnsupportedOperationException(" Condition " + condition + " is not suported for query on row key!");
	//
	//			}
	//		}
	//
	//	}

	//	public static String  getHbasefamily(String columnName)
	//	{
	//		int i=columnName.indexOf("@");
	//		if(i!=-1)return columnName.substring(0, i);
	//		return columnName;
	//		
	//	}
	//	
	//	public static String  getHbasequalifier(String columnName)
	//	{
	//		int i=columnName.indexOf("@");
	//		if(i!=-1)return columnName.substring(i+1);
	//		return columnName;
	//		
	//	}

}